import UIKit
import CoreImage
import CoreImage.CIFilterBuiltins

enum FilterType: Int, CaseIterable {
    case original = 0
    case vintage = 1
    case fresh = 2
    case warm = 3
    case cool = 4
    case film = 5
    case blackAndWhite = 6
    case softFocus = 7
    
    var name: String {
        switch self {
        case .original: return "原图"
        case .vintage: return "复古"
        case .fresh: return "清新"
        case .warm: return "暖阳"
        case .cool: return "冷调"
        case .film: return "胶片"
        case .blackAndWhite: return "黑白"
        case .softFocus: return "柔焦"
        }
    }
}

class FilterEngine {
    
    private let context: CIContext
    
    init() {
        // 使用GPU加速的上下文以获得更好的性能
        if let device = MTLCreateSystemDefaultDevice() {
            context = CIContext(mtlDevice: device)
        } else {
            context = CIContext()
        }
    }
    
    // MARK: - Main Filter Application Method
    func applyFilter(to image: UIImage, filterType: FilterType, intensity: Float = 1.0) -> UIImage {
        guard let ciImage = CIImage(image: image) else { return image }
        
        let filteredImage = applyFilterToCIImage(ciImage, filterType: filterType, intensity: intensity)
        return convertCIImageToUIImage(filteredImage) ?? image
    }
    
    // MARK: - Core Image Processing
    private func applyFilterToCIImage(_ ciImage: CIImage, filterType: FilterType, intensity: Float) -> CIImage {
        switch filterType {
        case .original:
            return ciImage
        case .vintage:
            return applyVintageFilter(to: ciImage, intensity: intensity)
        case .fresh:
            return applyFreshFilter(to: ciImage, intensity: intensity)
        case .warm:
            return applyWarmFilter(to: ciImage, intensity: intensity)
        case .cool:
            return applyCoolFilter(to: ciImage, intensity: intensity)
        case .film:
            return applyFilmFilter(to: ciImage, intensity: intensity)
        case .blackAndWhite:
            return applyBlackAndWhiteFilter(to: ciImage, intensity: intensity)
        case .softFocus:
            return applySoftFocusFilter(to: ciImage, intensity: intensity)
        }
    }
    
    // MARK: - Individual Filter Implementations
    
    // 复古滤镜 - 适合复古穿搭风格
    private func applyVintageFilter(to image: CIImage, intensity: Float) -> CIImage {
        var outputImage = image
        
        // 色彩调整
        if let colorAdjust = CIFilter(name: "CIColorControls") {
            colorAdjust.setValue(outputImage, forKey: kCIInputImageKey)
            colorAdjust.setValue(NSNumber(value: 0.8 + 0.2 * intensity), forKey: kCIInputSaturationKey)
            colorAdjust.setValue(NSNumber(value: 0.2 * intensity), forKey: kCIInputContrastKey)
            colorAdjust.setValue(NSNumber(value: -0.1 * intensity), forKey: kCIInputBrightnessKey)
            outputImage = colorAdjust.outputImage ?? outputImage
        }
        
        return outputImage
    }
    
    // 清新滤镜 - 适合清新自然的穿搭
    private func applyFreshFilter(to image: CIImage, intensity: Float) -> CIImage {
        var outputImage = image
        
        if let colorAdjust = CIFilter(name: "CIColorControls") {
            colorAdjust.setValue(outputImage, forKey: kCIInputImageKey)
            colorAdjust.setValue(NSNumber(value: 1.0 + 0.2 * intensity), forKey: kCIInputSaturationKey)
            colorAdjust.setValue(NSNumber(value: 0.1 * intensity), forKey: kCIInputBrightnessKey)
            colorAdjust.setValue(NSNumber(value: 0.1 * intensity), forKey: kCIInputContrastKey)
            outputImage = colorAdjust.outputImage ?? outputImage
        }
        
        return outputImage
    }
    
    // 暖阳滤镜 - 适合暖色调穿搭
    private func applyWarmFilter(to image: CIImage, intensity: Float) -> CIImage {
        var outputImage = image
        
        if let colorAdjust = CIFilter(name: "CIColorControls") {
            colorAdjust.setValue(outputImage, forKey: kCIInputImageKey)
            colorAdjust.setValue(NSNumber(value: 1.0 + 0.1 * intensity), forKey: kCIInputSaturationKey)
            colorAdjust.setValue(NSNumber(value: 0.15 * intensity), forKey: kCIInputBrightnessKey)
            outputImage = colorAdjust.outputImage ?? outputImage
        }
        
        return outputImage
    }
    
    // 冷调滤镜 - 适合冷色调穿搭
    private func applyCoolFilter(to image: CIImage, intensity: Float) -> CIImage {
        var outputImage = image
        
        if let colorAdjust = CIFilter(name: "CIColorControls") {
            colorAdjust.setValue(outputImage, forKey: kCIInputImageKey)
            colorAdjust.setValue(NSNumber(value: 0.9 + 0.05 * intensity), forKey: kCIInputSaturationKey)
            colorAdjust.setValue(NSNumber(value: 0.2 * intensity), forKey: kCIInputContrastKey)
            outputImage = colorAdjust.outputImage ?? outputImage
        }
        
        return outputImage
    }
    
    // 胶片滤镜 - 模拟胶片相机效果
    private func applyFilmFilter(to image: CIImage, intensity: Float) -> CIImage {
        var outputImage = image
        
        if let colorAdjust = CIFilter(name: "CIColorControls") {
            colorAdjust.setValue(outputImage, forKey: kCIInputImageKey)
            colorAdjust.setValue(NSNumber(value: 0.85 + 0.05 * intensity), forKey: kCIInputSaturationKey)
            colorAdjust.setValue(NSNumber(value: 0.3 * intensity), forKey: kCIInputContrastKey)
            colorAdjust.setValue(NSNumber(value: -0.05 * intensity), forKey: kCIInputBrightnessKey)
            outputImage = colorAdjust.outputImage ?? outputImage
        }
        
        return outputImage
    }
    
    // 黑白滤镜 - 经典黑白效果
    private func applyBlackAndWhiteFilter(to image: CIImage, intensity: Float) -> CIImage {
        var outputImage = image
        
        if let monoFilter = CIFilter(name: "CIColorMonochrome") {
            monoFilter.setValue(outputImage, forKey: kCIInputImageKey)
            monoFilter.setValue(CIColor(red: 0.6, green: 0.6, blue: 0.6), forKey: kCIInputColorKey)
            monoFilter.setValue(NSNumber(value: intensity), forKey: kCIInputIntensityKey)
            outputImage = monoFilter.outputImage ?? outputImage
        }
        
        if let contrastFilter = CIFilter(name: "CIColorControls") {
            contrastFilter.setValue(outputImage, forKey: kCIInputImageKey)
            contrastFilter.setValue(NSNumber(value: 0.3 * intensity), forKey: kCIInputContrastKey)
            contrastFilter.setValue(NSNumber(value: 0.1 * intensity), forKey: kCIInputBrightnessKey)
            outputImage = contrastFilter.outputImage ?? outputImage
        }
        
        return outputImage
    }
    
    // 柔焦滤镜 - 柔和的人像效果
    private func applySoftFocusFilter(to image: CIImage, intensity: Float) -> CIImage {
        var outputImage = image
        
        if let blurFilter = CIFilter(name: "CIGaussianBlur") {
            blurFilter.setValue(outputImage, forKey: kCIInputImageKey)
            blurFilter.setValue(NSNumber(value: 2.0 * intensity), forKey: kCIInputRadiusKey)
            let blurredImage = blurFilter.outputImage ?? outputImage
            
            // 混合原图和模糊图像
            if let blendFilter = CIFilter(name: "CISourceOverCompositing") {
                blendFilter.setValue(blurredImage, forKey: kCIInputImageKey)
                blendFilter.setValue(outputImage, forKey: kCIInputBackgroundImageKey)
                outputImage = blendFilter.outputImage ?? outputImage
            }
        }
        
        if let colorAdjust = CIFilter(name: "CIColorControls") {
            colorAdjust.setValue(outputImage, forKey: kCIInputImageKey)
            colorAdjust.setValue(NSNumber(value: 1.0 + 0.1 * intensity), forKey: kCIInputSaturationKey)
            colorAdjust.setValue(NSNumber(value: 0.1 * intensity), forKey: kCIInputBrightnessKey)
            outputImage = colorAdjust.outputImage ?? outputImage
        }
        
        return outputImage
    }
    
    // MARK: - Helper Methods
    private func convertCIImageToUIImage(_ ciImage: CIImage) -> UIImage? {
        guard let cgImage = context.createCGImage(ciImage, from: ciImage.extent) else {
            return nil
        }
        return UIImage(cgImage: cgImage)
    }
    
    // MARK: - Batch Processing for Preview
    func generateFilterPreviews(for image: UIImage, size: CGSize = CGSize(width: 150, height: 150)) -> [UIImage] {
        var previews: [UIImage] = []
        
        // 缩放图像以提高性能
        let resizedImage = resizeImage(image, to: size)
        
        for filterType in FilterType.allCases {
            let filteredImage = applyFilter(to: resizedImage, filterType: filterType)
            previews.append(filteredImage)
        }
        
        return previews
    }
    
    private func resizeImage(_ image: UIImage, to size: CGSize) -> UIImage {
        let renderer = UIGraphicsImageRenderer(size: size)
        return renderer.image { _ in
            image.draw(in: CGRect(origin: .zero, size: size))
        }
    }
}